[IA64] pte_xchg added
authorawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Wed, 17 May 2006 22:31:46 +0000 (16:31 -0600)
committerawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Wed, 17 May 2006 22:31:46 +0000 (16:31 -0600)
pte_xchg added to atomically exchange pte.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
xen/arch/ia64/xen/domain.c
xen/include/asm-ia64/linux-xen/asm/pgtable.h

index cb32d01ff9f564f1b51418aa1090b306fcddf69e..dd241f6db83449ab2ac456a4b25a4295c3efb14b 100644 (file)
@@ -746,6 +746,7 @@ __assign_new_domain_page(struct domain *d, unsigned long mpaddr, pte_t* pte)
     set_pte(pte, pfn_pte(maddr >> PAGE_SHIFT,
                          __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
 
+    mb ();
     //XXX CONFIG_XEN_IA64_DOM0_VP
     //    TODO racy
     set_gpfn_from_mfn(page_to_mfn(p), mpaddr >> PAGE_SHIFT);
@@ -803,6 +804,7 @@ __assign_domain_page(struct domain *d,
         set_pte(pte,
                 pfn_pte(physaddr >> PAGE_SHIFT,
                         __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
+        mb ();
     } else
         printk("%s: mpaddr %lx already mapped!\n", __func__, mpaddr);
 }
@@ -1123,13 +1125,13 @@ assign_domain_page_replace(struct domain *d, unsigned long mpaddr,
     struct mm_struct *mm = &d->arch.mm;
     pte_t* pte;
     pte_t old_pte;
+    pte_t npte;
 
     pte = lookup_alloc_domain_pte(d, mpaddr);
 
     // update pte
-    old_pte = ptep_get_and_clear(mm, mpaddr, pte);
-    set_pte(pte, pfn_pte(mfn,
-                         __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX)));
+    npte = pfn_pte(mfn, __pgprot(__DIRTY_BITS | _PAGE_PL_2 | _PAGE_AR_RWX));
+    old_pte = ptep_xchg(mm, mpaddr, pte, npte);
     if (!pte_none(old_pte)) {
         unsigned long old_mfn;
         struct page_info* old_page;
index dde496483013075e1bb31cd4438fb53d36e109c7..54539200c249a3963b7df78d88c58a3d8a7fe4ea 100644 (file)
@@ -397,6 +397,18 @@ ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 #endif
 }
 
+static inline pte_t
+ptep_xchg(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t npte)
+{
+#ifdef CONFIG_SMP
+       return __pte(xchg((long *) ptep, pte_val(npte)));
+#else
+       pte_t pte = *ptep;
+       set_pte (ptep, npte);
+       return pte;
+#endif
+}
+
 #ifndef XEN
 static inline void
 ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep)